#ifndef __I264E_THREADPOOL_H__
#define __I264E_THREADPOOL_H__

#include <i264e_osdep.h>

#define i264e_stack_align(func,...) func(__VA_ARGS__)

typedef struct {
	void *p_elem;
	void (*elem_free)(void *p_elem);
} i264e_elem_t;

/* synchronized elem list */
typedef struct {
	i264e_elem_t *list;
	int i_max_size;
	int i_size;
	i264e_pthread_mutex_t     mutex;
	i264e_pthread_cond_t      cv_fill;  /* event signaling that the list became fuller */
	i264e_pthread_cond_t      cv_empty; /* event signaling that the list became emptier */
} i264e_sync_elem_list_t;

typedef struct {
	int            exit;
	int            threads;
	i264e_pthread_t *thread_handle;
	void           (*init_func)(void *);
	void           *init_arg;

	/* requires a synchronized list structure and associated methods */
	i264e_sync_elem_list_t uninit; /* list of jobs that are awaiting use */
	i264e_sync_elem_list_t run;    /* list of jobs that are queued for processing by the pool */
	i264e_sync_elem_list_t done;   /* list of jobs that have finished processing */
} i264e_threadpool_t;

extern int i264e_threadpool_init(i264e_threadpool_t **p_pool, int threads,
		void (*init_func)(void *), void *init_arg);
extern void i264e_threadpool_run(i264e_threadpool_t *pool, void *(*func)(void *), void *arg);
extern void *i264e_threadpool_wait(i264e_threadpool_t *pool, void *arg);
extern void *i264e_threadpool_get_done(i264e_threadpool_t *pool, void **donehandler);
extern int i264e_threadpool_release_done(i264e_threadpool_t *pool, void *donehandler);
extern void i264e_threadpool_delete(i264e_threadpool_t *pool);

#endif /* __I264E_THREADPOOL_H__ */
